const TeaBatch = require('../models/TeaBatch');
const logger = require('../utils/logger');
const blockchainService = require('../services/blockchainService');
const mongoose = require('mongoose');
const {
  successResponse,
  errorResponse,
  notFoundResponse,
  paginatedResponse,
  internalErrorResponse
} = require('../utils/response');

// 辅助函数：构建批次查询条件
const buildBatchQuery = (batchId) => {
  if (mongoose.Types.ObjectId.isValid(batchId) && batchId.length === 24) {
    return {
      $or: [
        { _id: batchId },
        { batchId: batchId }
      ]
    };
  }
  return { batchId: batchId };
};

/**
 * 创建茶叶批次
 */
const createBatch = async (req, res) => {
  try {
    const batchData = {
      ...req.body,
      createdBy: req.user._id
    };

    // 生成批次ID
    const timestamp = Date.now().toString();
    const randomSuffix = Math.random().toString(36).substring(2, 8).toUpperCase();
    batchData.batchId = `TEA${timestamp.slice(-8)}${randomSuffix}`;

    // 确保 production 对象存在
    if (!batchData.production) {
      batchData.production = {};
    }

    // 自动设置农民相关字段
    batchData.production.farmerId = req.user._id;
    
    // 如果用户没有以太坊地址，生成一个模拟地址
    if (!req.user.ethereumAddress) {
      // 生成一个模拟的以太坊地址用于开发环境
      const mockAddress = `0x${Math.random().toString(16).slice(2, 42).padStart(40, '0')}`;
      batchData.production.farmerAddress = mockAddress;
    } else {
      batchData.production.farmerAddress = req.user.ethereumAddress;
    }

    const batch = new TeaBatch(batchData);
    await batch.save();

    // 尝试在区块链上创建批次
    try {
      const blockchainResult = await blockchainService.createBatch({
        batchId: batch.batchId,
        name: batch.name,
        variety: batch.variety
      });
      
      if (blockchainResult.success) {
        // 保存区块链信息到批次
        batch.blockchain = {
          tokenId: blockchainResult.tokenId,
          txHash: blockchainResult.txHash,
          blockNumber: blockchainResult.blockNumber
        };
        await batch.save();

        logger.info('批次区块链创建成功:', {
          batchId: batch.batchId,
          tokenId: blockchainResult.tokenId,
          txHash: blockchainResult.txHash
        });
      }
    } catch (blockchainError) {
      logger.warn('区块链批次创建失败，但数据库记录已创建:', {
        batchId: batch.batchId,
        error: blockchainError.message
      });
    }

    logger.info('茶叶批次创建成功:', {
      batchId: batch.batchId,
      createdBy: req.user._id,
      name: batch.name
    });

    return successResponse(res, { batch }, '茶叶批次创建成功', 201);

  } catch (error) {
    logger.error('创建茶叶批次失败:', {
      error: error.message,
      stack: error.stack,
      requestBody: req.body,
      userId: req.user._id
    });

    return internalErrorResponse(res, error);
  }
};

/**
 * 获取茶叶批次列表
 */
const getBatchList = async (req, res) => {
  try {
    const {
      page = 1,
      limit = 10,
      status,
      variety,
      keyword,
      startDate,
      endDate,
      createdBy
    } = req.query;

    // 构建查询条件
    const query = {};

    // 根据用户角色过滤数据
    if (req.user.role !== 'admin') {
      // 非管理员用户只能看到自己创建的或相关的批次
      if (req.user.role === 'farmer') {
        query.createdBy = req.user._id;
      } else if (req.user.role === 'logistics') {
        // 物流角色可以查看生产完成和运输中的批次
        query.status = { $in: ['production', 'logistics'] };
      } else if (req.user.role === 'merchant') {
        query.$or = [
          { 'sales.merchantId': req.user._id },
          { status: { $in: ['logistics', 'sales'] } }
        ];
      } else {
        // consumer 可以查看已上架销售的批次
        query.status = { $in: ['sales', 'consumed'] };
      }
    }

    if (status) {
      query.status = status;
    }

    if (variety) {
      query.variety = { $regex: variety, $options: 'i' };
    }

    if (keyword) {
      query.$or = [
        { name: { $regex: keyword, $options: 'i' } },
        { batchId: { $regex: keyword, $options: 'i' } },
        { variety: { $regex: keyword, $options: 'i' } },
        { 'production.origin.province': { $regex: keyword, $options: 'i' } },
        { 'production.origin.city': { $regex: keyword, $options: 'i' } }
      ];
    }

    if (startDate && endDate) {
      query.createdAt = {
        $gte: new Date(startDate),
        $lte: new Date(endDate)
      };
    }

    if (createdBy && req.user.role === 'admin') {
      query.createdBy = createdBy;
    }

    // 计算分页
    const skip = (parseInt(page) - 1) * parseInt(limit);

    // 查询批次
    const [batches, total] = await Promise.all([
      TeaBatch.find(query)
        .populate('createdBy', 'username email role')
        .populate('logistics.logisticsId', 'username email')
        .populate('sales.merchantId', 'username email')
        .sort({ createdAt: -1 })
        .skip(skip)
        .limit(parseInt(limit)),
      TeaBatch.countDocuments(query)
    ]);

    return paginatedResponse(res, batches, {
      page: parseInt(page),
      limit: parseInt(limit),
      total
    }, '获取批次列表成功');

  } catch (error) {
    logger.error('获取批次列表失败:', {
      error: error.message,
      stack: error.stack,
      query: req.query,
      userId: req.user._id
    });

    return internalErrorResponse(res, error);
  }
};

/**
 * 获取茶叶批次详情
 */
const getBatchById = async (req, res) => {
  try {
    const { batchId } = req.params;
    
    logger.info('获取批次详情请求:', {
      batchId,
      userRole: req.user?.role,
      userId: req.user?._id,
      username: req.user?.username
    });

    // 先查询批次基本信息
    const batchQuery = buildBatchQuery(batchId);
    logger.info('批次查询条件:', batchQuery);
    
    const batch = await TeaBatch.findOne(batchQuery);
    
    if (batch) {
      logger.info('找到批次:', {
        batchId: batch.batchId,
        status: batch.status,
        createdBy: batch.createdBy,
        name: batch.name
      });
    } else {
      logger.info('未找到批次');
    }

    if (!batch) {
      return notFoundResponse(res, '茶叶批次');
    }

    // 检查权限 - 对于公开查询，允许查看销售状态的批次
    logger.info('批次详情访问权限检查:', {
      batchId: batch.batchId,
      batchStatus: batch.status,
      userRole: req.user.role,
      userId: req.user._id,
      batchCreator: batch.createdBy
    });

    // 简化权限检查逻辑，分步骤检查
    let hasAccess = false;
    let accessReason = '';

    // 1. 管理员可以访问所有批次
    if (req.user.role === 'admin') {
      hasAccess = true;
      accessReason = 'admin role';
    }
    // 2. 创建者可以访问自己的批次
    else if (req.user._id && batch.createdBy && batch.createdBy.toString() === req.user._id.toString()) {
      hasAccess = true;
      accessReason = 'batch creator';
    }
    // 3. 物流角色可以查看所有批次（临时修改用于调试）
    else if (req.user.role === 'logistics') {
      hasAccess = true;
      accessReason = 'logistics role (temporary access)';
    }
    // 4. 商家角色权限
    else if (req.user.role === 'merchant' && ['logistics', 'sales'].includes(batch.status)) {
      hasAccess = true;
      accessReason = 'merchant role with appropriate status';
    }
    // 5. 消费者权限
    else if (req.user.role === 'consumer') {
      if (req.user._id === null) {
        // 公开查询 - 允许查看所有状态的批次（溯源查询）
        hasAccess = true;
        accessReason = 'public trace query';
      } else if (['sales', 'consumed'].includes(batch.status)) {
        // 已登录消费者 - 只能查看销售中和已消费的批次
        hasAccess = true;
        accessReason = 'consumer role with appropriate status';
      }
    }

    logger.info('权限检查结果:', { 
      hasAccess, 
      accessReason,
      userRole: req.user.role,
      batchStatus: batch.status 
    });

    if (!hasAccess) {
      return errorResponse(res, '无权访问此批次信息', 403);
    }

    return successResponse(res, { batch }, '获取批次详情成功');

  } catch (error) {
    logger.error('获取批次详情失败:', {
      error: error.message,
      stack: error.stack,
      batchId: req.params.batchId,
      userId: req.user._id
    });

    return internalErrorResponse(res, error);
  }
};

/**
 * 更新茶叶批次基本信息
 */
const updateBatch = async (req, res) => {
  try {
    const { batchId } = req.params;
    const updates = req.body;

    const batch = await TeaBatch.findOne(buildBatchQuery(batchId));

    if (!batch) {
      return notFoundResponse(res, '茶叶批次');
    }

    // 权限检查：只有创建者或管理员可以更新基本信息
    if (req.user.role !== 'admin' && batch.createdBy.toString() !== req.user._id.toString()) {
      return errorResponse(res, '只能修改自己创建的批次', 403);
    }

    // 限制可更新的字段
    const allowedUpdates = ['name', 'variety', 'grade', 'description'];
    const filteredUpdates = {};
    
    allowedUpdates.forEach(field => {
      if (updates[field] !== undefined) {
        filteredUpdates[field] = updates[field];
      }
    });

    if (Object.keys(filteredUpdates).length === 0) {
      return errorResponse(res, '没有可更新的字段', 400);
    }

    // 更新批次信息
    Object.assign(batch, filteredUpdates);
    batch.updatedAt = new Date();
    await batch.save();

    logger.info('茶叶批次更新成功:', {
      batchId: batch.batchId,
      updatedFields: Object.keys(filteredUpdates),
      updatedBy: req.user._id
    });

    return successResponse(res, { batch }, '批次信息更新成功');

  } catch (error) {
    logger.error('更新茶叶批次失败:', {
      error: error.message,
      stack: error.stack,
      batchId: req.params.batchId,
      updates: req.body,
      userId: req.user._id
    });

    return internalErrorResponse(res, error);
  }
};

/**
 * 添加生产记录
 */
const addProductionRecord = async (req, res) => {
  try {
    const { batchId } = req.params;
    const productionData = req.body;

    const batch = await TeaBatch.findOne(buildBatchQuery(batchId));

    if (!batch) {
      return notFoundResponse(res, '茶叶批次');
    }

    // 权限检查：只有茶农或管理员可以添加生产记录
    if (!['farmer', 'admin'].includes(req.user.role)) {
      return errorResponse(res, '只有茶农可以添加生产记录', 403);
    }

    if (req.user.role === 'farmer' && batch.createdBy.toString() !== req.user._id.toString()) {
      return errorResponse(res, '只能为自己的批次添加生产记录', 403);
    }

    // 更新生产信息
    batch.production = {
      ...batch.production,
      ...productionData,
      recordedAt: new Date(),
      recordedBy: req.user._id
    };

    batch.status = 'production';
    batch.updatedAt = new Date();
    await batch.save();

    logger.info('生产记录添加成功:', {
      batchId: batch.batchId,
      recordedBy: req.user._id
    });

    return successResponse(res, { batch }, '生产记录添加成功');

  } catch (error) {
    logger.error('添加生产记录失败:', {
      error: error.message,
      stack: error.stack,
      batchId: req.params.batchId,
      productionData: req.body,
      userId: req.user._id
    });

    return internalErrorResponse(res, error);
  }
};

/**
 * 添加物流记录
 */
const addLogisticsRecord = async (req, res) => {
  try {
    const { batchId } = req.params;
    const logisticsData = req.body;

    const batch = await TeaBatch.findOne(buildBatchQuery(batchId));

    if (!batch) {
      return notFoundResponse(res, '茶叶批次');
    }

    // 权限检查：只有物流方或管理员可以添加物流记录
    if (!['logistics', 'admin'].includes(req.user.role)) {
      return errorResponse(res, '只有物流方可以添加物流记录', 403);
    }

    // 添加物流记录
    const logisticsRecord = {
      ...logisticsData,
      recordedAt: new Date(),
      logisticsId: req.user._id,
      logisticsAddress: req.user.address
    };

    batch.logistics.push(logisticsRecord);
    batch.status = 'logistics';
    batch.updatedAt = new Date();
    await batch.save();

    logger.info('物流记录添加成功:', {
      batchId: batch.batchId,
      stage: logisticsData.stage,
      logisticsId: req.user._id
    });

    return successResponse(res, { batch }, '物流记录添加成功');

  } catch (error) {
    logger.error('添加物流记录失败:', {
      error: error.message,
      stack: error.stack,
      batchId: req.params.batchId,
      logisticsData: req.body,
      userId: req.user._id
    });

    return internalErrorResponse(res, error);
  }
};

/**
 * 添加销售记录
 */
const addSalesRecord = async (req, res) => {
  try {
    const { batchId } = req.params;
    const salesData = req.body;

    const batch = await TeaBatch.findOne(buildBatchQuery(batchId));

    if (!batch) {
      return notFoundResponse(res, '茶叶批次');
    }

    // 权限检查：只有商家或管理员可以添加销售记录
    if (!['merchant', 'admin'].includes(req.user.role)) {
      return errorResponse(res, '只有商家可以添加销售记录', 403);
    }

    // 添加销售记录
    const salesRecord = {
      ...salesData,
      recordedAt: new Date(),
      merchantId: req.user._id,
      merchantAddress: req.user.address
    };

    batch.sales.push(salesRecord);
    batch.status = 'sales';
    batch.updatedAt = new Date();
    await batch.save();

    logger.info('销售记录添加成功:', {
      batchId: batch.batchId,
      storeName: salesData.storeInfo?.storeName,
      merchantId: req.user._id
    });

    return successResponse(res, { batch }, '销售记录添加成功');

  } catch (error) {
    logger.error('添加销售记录失败:', {
      error: error.message,
      stack: error.stack,
      batchId: req.params.batchId,
      salesData: req.body,
      userId: req.user._id
    });

    return internalErrorResponse(res, error);
  }
};

/**
 * 获取批次统计信息
 */
const getBatchStats = async (req, res) => {
  try {
    let matchQuery = {};

    // 根据用户角色过滤统计数据
    if (req.user.role === 'farmer') {
      matchQuery.createdBy = req.user._id;
    } else if (req.user.role === 'logistics') {
      matchQuery['logistics.logisticsId'] = req.user._id;
    } else if (req.user.role === 'merchant') {
      matchQuery['sales.merchantId'] = req.user._id;
    }

    const [
      totalBatches,
      statusStats,
      varietyStats,
      recentBatches
    ] = await Promise.all([
      TeaBatch.countDocuments(matchQuery),
      TeaBatch.aggregate([
        { $match: matchQuery },
        { $group: { _id: '$status', count: { $sum: 1 } } },
        { $sort: { count: -1 } }
      ]),
      TeaBatch.aggregate([
        { $match: matchQuery },
        { $group: { _id: '$variety', count: { $sum: 1 } } },
        { $sort: { count: -1 } },
        { $limit: 10 }
      ]),
      TeaBatch.find(matchQuery)
        .select('batchId name variety status createdAt')
        .populate('createdBy', 'username')
        .sort({ createdAt: -1 })
        .limit(5)
    ]);

    const stats = {
      total: totalBatches,
      byStatus: statusStats.reduce((acc, item) => {
        acc[item._id] = item.count;
        return acc;
      }, {}),
      byVariety: varietyStats,
      recent: recentBatches
    };

    return successResponse(res, { stats }, '获取批次统计成功');

  } catch (error) {
    logger.error('获取批次统计失败:', {
      error: error.message,
      stack: error.stack,
      userId: req.user._id,
      userRole: req.user.role
    });

    return internalErrorResponse(res, error);
  }
};

/**
 * 搜索茶叶批次
 */
const searchBatches = async (req, res) => {
  try {
    const { keyword, page = 1, limit = 10 } = req.query;

    if (!keyword) {
      return errorResponse(res, '搜索关键词不能为空', 400);
    }

    const query = TeaBatch.searchBatches(keyword);
    
    // 根据用户角色过滤搜索结果
    if (req.user.role !== 'admin') {
      if (req.user.role === 'farmer') {
        query.find({ createdBy: req.user._id });
      } else if (req.user.role === 'consumer') {
        query.find({ status: { $in: ['sales', 'consumed'] } });
      }
    }

    const skip = (parseInt(page) - 1) * parseInt(limit);
    
    const [batches, total] = await Promise.all([
      query.populate('createdBy', 'username email')
        .sort({ score: { $meta: 'textScore' }, createdAt: -1 })
        .skip(skip)
        .limit(parseInt(limit)),
      TeaBatch.countDocuments(query.getQuery())
    ]);

    return paginatedResponse(res, batches, {
      page: parseInt(page),
      limit: parseInt(limit),
      total
    }, '搜索完成');

  } catch (error) {
    logger.error('搜索茶叶批次失败:', {
      error: error.message,
      stack: error.stack,
      keyword: req.query.keyword,
      userId: req.user._id
    });

    return internalErrorResponse(res, error);
  }
};

module.exports = {
  createBatch,
  getBatchList,
  getBatchById,
  updateBatch,
  addProductionRecord,
  addLogisticsRecord,
  addSalesRecord,
  getBatchStats,
  searchBatches
};